package phoenix.core.helpers;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.HttpsURLConnection;
import java.net.HttpURLConnection;

import core.config.Config;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.testng.TestException;

import phoenix.core.PhoenixManager;
import phoenix.core.base.HelperBase;
import core.ApplicationManager;

public class HttpUrlHelper extends HelperBase
{
	protected static ApplicationManager manager;

	public HttpUrlHelper(PhoenixManager p_phoenix)
	{
		super(p_phoenix);
	}

	private List<String> cookies;
	private HttpsURLConnection sslConnection;
	private HttpURLConnection connection;
	private final String USER_AGENT = "Mozilla/5.0";

	public void sendPost(String url, String postParams) throws IOException
	{
		if (Config.BUILD.equals(Config.BUILD_LIVE))
		{
			this.sendPostSSL(url, postParams);
		}
		else
		{
			this.sendPostNoSSL(url, postParams);
		}
	}

	public void getRequest(String url)
	{
		if (Config.BUILD.equals(Config.BUILD_LIVE))
		{
			this.getRequestSSL(url);
		}
		else
		{
			this.getRequestNoSSL(url);
		}
	}

	public String getPageContent(String url)
	{
		log().info("URL=> " + url);

		if (Config.BUILD.equals(Config.BUILD_LIVE))
		{
			return this.getPageContentSSL(url);
		}
		else
		{
			return this.getPageContentNoSSL(url);
		}
	}

	private void sendPostNoSSL(String url, String postParams) throws IOException
	{
		try
		{
			URL obj = new URL(url);

			connection = (HttpURLConnection) obj.openConnection();

			// Acts like a browser
			connection.setUseCaches(false);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("User-Agent", USER_AGENT);
			connection.setRequestProperty("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
			connection.setRequestProperty("Connection", "keep-alive");
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			connection.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
			connection.setDoOutput(true);
			connection.setDoInput(true);

			// Send post request
			DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
			wr.writeBytes(postParams);
			wr.flush();
			wr.close();

			int responseCode = connection.getResponseCode();
			System.out.println("\nSending 'POST' request to URL : " + url);
			System.out.println("Post parameters : " + postParams);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();

		}
		catch (Exception p_ex)
		{
			throw new TestException("Cant send a POST data!" + "\n" + "URL: " + url + "\n" + p_ex);
		}

	}

	private String getRequestNoSSL(String url)
	{
		String content = "";
		try
		{
			URL obj = new URL(url);
			connection = (HttpURLConnection) obj.openConnection();

			// default is GET
			connection.setRequestMethod("GET");

			connection.setUseCaches(false);

			// act like a browser
			connection.setRequestProperty("User-Agent", USER_AGENT);

			connection.setRequestProperty("Accept",
				"application/json, text/javascript, */*; q=0.01");
			connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
			connection.setRequestProperty("X-Requested-With", "XMLHttpRequest");

			if (cookies != null)
			{
				for (String cookie : this.cookies)
				{
					sslConnection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
				}
			}
			int responseCode = connection.getResponseCode();

			if (responseCode == 500 && url.contains("userPermissions"))
			{
				return "Error: 500";
			}

			System.out.println("\nSending 'GET' request to URL : " + url);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();

			// Get the response cookies
			setCookies(connection.getHeaderFields().get("Set-Cookie"));

			content = response.toString();
		}
		catch (Exception p_ex)
		{
			throw new TestException("Can't get a page content" + p_ex);
		}
		return content;

	}

	private String getPageContentNoSSL(String url)
	{
		String content = "";
		try
		{
			URL obj = new URL(url);
			connection = (HttpURLConnection) obj.openConnection();

			// default is GET
			connection.setRequestMethod("GET");

			connection.setUseCaches(false);

			// act like a browser
			connection.setRequestProperty("User-Agent", USER_AGENT);

			connection.setRequestProperty("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			connection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

			if (cookies != null)
			{
				for (String cookie : this.cookies)
				{
					connection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
				}
			}
			int responseCode = connection.getResponseCode();

			if (responseCode == 500 && url.contains("userPermissions"))
			{
				return "Error: 500";
			}

			System.out.println("\nSending 'GET' request to URL : " + url);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(connection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();

			// Get the response cookies
			setCookies(connection.getHeaderFields().get("Set-Cookie"));

			content = response.toString();
		}
		catch (Exception p_ex)
		{
			throw new TestException("Can't get a page content" + p_ex);
		}
		return content;

	}

	private void sendPostSSL(String url, String postParams) throws IOException
	{
		try
		{
			URL obj = new URL(url);

			sslConnection = (HttpsURLConnection) obj.openConnection();

			// Acts like a browser
			sslConnection.setUseCaches(false);
			sslConnection.setRequestMethod("POST");
			sslConnection.setRequestProperty("User-Agent", USER_AGENT);
			sslConnection.setRequestProperty("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			sslConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
			sslConnection.setRequestProperty("Connection", "keep-alive");
			sslConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			sslConnection.setRequestProperty("Content-Length", Integer.toString(postParams.length()));
			sslConnection.setDoOutput(true);
			sslConnection.setDoInput(true);

			// Send post request
			DataOutputStream wr = new DataOutputStream(sslConnection.getOutputStream());
			wr.writeBytes(postParams);
			wr.flush();
			wr.close();

			int responseCode = sslConnection.getResponseCode();
			System.out.println("\nSending 'POST' request to URL : " + url);
			System.out.println("Post parameters : " + postParams);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(sslConnection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();
		}
		catch (Exception p_ex)
		{
			throw new TestException("Cant send a POST data!" + "\n" + "URL: " + url + "\n" + p_ex);
		}

	}

	private String getRequestSSL(String url)
	{
		String content = "";
		try
		{
			URL obj = new URL(url);
			sslConnection = (HttpsURLConnection) obj.openConnection();

			// default is GET
			sslConnection.setRequestMethod("GET");

			sslConnection.setUseCaches(false);

			// act like a browser
			sslConnection.setRequestProperty("User-Agent", USER_AGENT);

			sslConnection.setRequestProperty("Accept",
				"application/json, text/javascript, */*; q=0.01");
			sslConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
			sslConnection.setRequestProperty("X-Requested-With", "XMLHttpRequest");

			if (cookies != null)
			{
				for (String cookie : this.cookies)
				{
					sslConnection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
				}
			}
			int responseCode = sslConnection.getResponseCode();

			if (responseCode == 500 && url.contains("userPermissions"))
			{
				return "Error: 500";
			}

			System.out.println("\nSending 'GET' request to URL : " + url);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(sslConnection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();

			// Get the response cookies
			setCookies(sslConnection.getHeaderFields().get("Set-Cookie"));

			content = response.toString();
		}
		catch (Exception p_ex)
		{
			throw new TestException("Can't get a page content" + p_ex);
		}
		return content;

	}

	private String getPageContentSSL(String url)
	{
		String content = "";
		try
		{
			URL obj = new URL(url);
			sslConnection = (HttpsURLConnection) obj.openConnection();

			// default is GET
			sslConnection.setRequestMethod("GET");

			sslConnection.setUseCaches(false);

			// act like a browser
			sslConnection.setRequestProperty("User-Agent", USER_AGENT);

			sslConnection.setRequestProperty("Accept",
				"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			sslConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

			if (cookies != null)
			{
				for (String cookie : this.cookies)
				{
					sslConnection.addRequestProperty("Cookie", cookie.split(";", 1)[0]);
				}
			}
			int responseCode = sslConnection.getResponseCode();

			if (responseCode == 500 && url.contains("userPermissions"))
			{
				return "Error: 500";
			}

			System.out.println("\nSending 'GET' request to URL : " + url);
			System.out.println("Response Code : " + responseCode);

			BufferedReader in =
				new BufferedReader(new InputStreamReader(sslConnection.getInputStream()));
			String inputLine;
			StringBuffer response = new StringBuffer();

			while ((inputLine = in.readLine()) != null)
			{
				response.append(inputLine);
			}
			in.close();

			// Get the response cookies
			setCookies(sslConnection.getHeaderFields().get("Set-Cookie"));

			content = response.toString();
		}
		catch (Exception p_ex)
		{
			throw new TestException("Can't get a page content" + p_ex);
		}
		return content;

	}

	public String getLoginFormParams(String html, String username, String password)
	{
		String return_result = null;

		try
		{
			Document doc = Jsoup.parse(html);
			Element loginform = (Element) doc.getElementById("user-login-form");
			Elements inputElements = loginform.getElementsByTag("input");
			List<String> paramList = new ArrayList<String>();

			for (Element inputElement : inputElements)
			{
				String key = inputElement.attr("name");
				String value = inputElement.attr("value");

				if (key.equals("AdminLoginForm[login]"))
					value = username;
				else if (key.equals("AdminLoginForm[password]"))
					value = password;
				paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8"));
			}
			return_result = this.buildParams(paramList);

		}
		catch (Exception p_ex)
		{
			throw new TestException("Cannot get FORM data from admin panel on Index page: " + p_ex);
		}
		return return_result;
	}

	public String buildParams(List<String> paramList)
	{
		// build parameters list
		StringBuilder result = new StringBuilder();
		for (String param : paramList)
		{
			if (result.length() == 0)
			{
				result.append(param);
			}
			else
			{
				result.append("&" + param);
			}
		}
		return result.toString();
	}

	public List<String> getCookies()
	{
		return cookies;
	}

	public void setCookies(List<String> cookies)
	{
		this.cookies = cookies;
	}

}
